package com.shangma.cn.commons.utils;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.shangma.cn.commons.http.AxiosStatus;
import com.shangma.cn.entity.LoginAdmin;
import com.shangma.cn.entity.base.impl.Admin;
import com.shangma.cn.exception.base.impl.ApiException;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.print.attribute.standard.JobSheets;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.UUID;

/**
 * 开发人员: 辉哥真球帅
 * 联系方式: zhengzhoudaxuevip@163.com
 * 创建时间: 2021/10/13  14:40
 * 文件含义:
 * <p>
 * //TOKEN中存储UUID
 * Redis  又依UUID为key 用户的登录信息为value 存到redis中
 */
@Component
public class TokenService {
    public static final String secret = "7bca149eb5c7fa9a400d9f628bd53a6b";
    public static final String PREFIX = "loginAdmin:";


    /**
     * 缓存登录用户和返回token
     */

    public String cacheLoginAdminAndCreateToken(Admin admin) {
        String uuid = UUID.randomUUID().toString();
        LoginAdmin loginAdmin = new LoginAdmin();
        loginAdmin.setUuid(uuid);
        loginAdmin.setAdmin(admin);
        //缓存loginAdmin
        setLoginAdminCache(loginAdmin);
        return generatorToken(uuid);


    }

    /**
     * 缓存登录用户
     */
    public void setLoginAdminCache(LoginAdmin loginAdmin) {
        CacheUtils.setCache(PREFIX + loginAdmin.getUuid(), JsonUtils.obj2Str(loginAdmin));
    }


    /**
     * 生成Token
     */
    public String generatorToken(String uuid) {
        Algorithm algorithm = Algorithm.HMAC256(secret);
        String token = JWT.create()
                .withIssuer("尚马教育")
                .withSubject("token信息")
                .withClaim("uuid", uuid) //UUid 放到token中
                .sign(algorithm);
        return token;
    }

    /**
     * 解析Token
     */
    public DecodedJWT verifyToken(HttpServletRequest request) {
        String token = request.getHeader("Authorization").split(" ")[1];
        Algorithm algorithm = Algorithm.HMAC256(secret);
        JWTVerifier verifier = JWT.require(algorithm)
                .withIssuer("尚马教育")
                .withSubject("token信息")
                .build(); //Reusable verifier instance
        DecodedJWT jwt = verifier.verify(token);
        return jwt;
    }


    /**
     * 获得uuid的函数
     */

    public String getUUId(HttpServletRequest request) {
        return verifyToken(request).getClaim("uuid").asString();
    }


    /**
     * 获取缓存的用户
     */

    public LoginAdmin getCacheLoginAdmin() {
        String uuId = getUUId(getRequest());
        String cache = CacheUtils.getCache(PREFIX + uuId);
        LoginAdmin loginAdmin = JsonUtils.str2Obj(cache, LoginAdmin.class);
        return loginAdmin;
    }


    /**
     * 获得登录的id值
     */
    public long getLoginAdminId() {
        return getCacheLoginAdmin().getAdmin().getId();
    }


    /**
     * 获取全局Request
     */
    public HttpServletRequest getRequest() {
        ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        return requestAttributes.getRequest();
    }

    /**
     * 获取全局Response
     */
    public HttpServletResponse getResponse() {
        ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        return requestAttributes.getResponse();
    }


    public boolean checkToken(HttpServletRequest request) {
        String token = request.getHeader("Authorization");
        if (StringUtils.isEmpty(token)) {
            //还未登录
            throw new ApiException(AxiosStatus.TOKEN_ERROR);
        }

        if (!token.startsWith("Bearer ")) {
            //token格式不正确
            throw new ApiException(AxiosStatus.TOKEN_ERROR);
        }
        String[] s = token.split(" ");
        if (s.length != 2) {
            //传的格式不正确
            throw new ApiException(AxiosStatus.TOKEN_ERROR);
        }

        DecodedJWT decodedJWT = null;
        try {
            decodedJWT = verifyToken(request);
        } catch (Exception e) {
            //token解析错误
            throw new ApiException(AxiosStatus.TOKEN_ERROR);
        }
        if (decodedJWT == null) {
            //解析错误
            throw new ApiException(AxiosStatus.TOKEN_ERROR);
        }

        return true;

    }
}
